package boot

import (
	"gitee.com/tietang/terrace-go/v2/base"
	log "github.com/sirupsen/logrus"
	"github.com/tietang/props/v3/ini"
	"github.com/tietang/props/v3/kvs"
	"reflect"
)

//应用程序
type BootApplication struct {
	IsTest     bool
	conf       kvs.ConfigSource
	starterCtx base.StarterContext
	Callback   func()
}

//构造系统
func NewByFile(file ...string) *BootApplication {
	//加载和解析配置文件
	conf := ini.NewIniFileCompositeConfigSource(file...)
	return New(conf)
}

//构造系统
func New(conf kvs.ConfigSource) *BootApplication {
	e := &BootApplication{conf: conf, starterCtx: base.StarterContext{}}
	e.starterCtx.SetProps(conf)
	return e
}

func (b *BootApplication) RapidStart() {
	//1. 初始化starter
	b.Init()
	//2. 安装starter
	b.Setup()
	//3. 启动starter
	b.Start()
}

//程序初始化
func (e *BootApplication) Init() {
	log.Info("Initializing starters...")
	for _, v := range base.GetStarters() {
		typ := reflect.TypeOf(v)
		log.Debugf("Initializing: PriorityGroup=%d,Priority=%d,type=%s", v.PriorityGroup(), v.Priority(), typ.String())
		v.Init(e.starterCtx)
	}
}

//程序安装
func (e *BootApplication) Setup() {

	log.Info("Setup starters...")
	for _, v := range base.GetStarters() {
		typ := reflect.TypeOf(v)
		log.Debug("Setup: ", typ.String())
		v.Setup(e.starterCtx)
	}

}

//程序开始运行，开始接受调用
func (e *BootApplication) Start() {

	log.Info("Starting starters...")
	for i, v := range base.GetStarters() {

		typ := reflect.TypeOf(v)
		msg := "NoBlocking"
		if v.StartBlocking() {
			msg = "Blocking"
		}
		log.Debugf("Starting[%s]: %s \n", msg, typ.String())
		if v.StartBlocking() {
			if i+1 == len(base.GetStarters()) {
				v.Start(e.starterCtx)
			} else {
				go v.Start(e.starterCtx)
			}
		} else {
			v.Start(e.starterCtx)
		}

	}
}

//程序开始运行，开始接受调用
func (e *BootApplication) Stop() {

	log.Info("Stoping starters...")
	for _, v := range base.GetStarters() {
		typ := reflect.TypeOf(v)
		log.Debug("Stoping: ", typ.String())
		v.Stop(e.starterCtx)
	}
}
